home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / compiler / pycodegen.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  50KB  |  1,637 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. import imp
  5. import os
  6. import marshal
  7. import struct
  8. import sys
  9. from cStringIO import StringIO
  10. from compiler import ast, parse, walk, syntax
  11. from compiler import pyassem, misc, future, symbols
  12. from compiler.consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL
  13. from compiler.consts import CO_VARARGS, CO_VARKEYWORDS, CO_NEWLOCALS, CO_NESTED, CO_GENERATOR, CO_FUTURE_DIVISION, CO_FUTURE_ABSIMPORT, CO_FUTURE_WITH_STATEMENT
  14. from compiler.pyassem import TupleArg
  15.  
  16. try:
  17.     VERSION = sys.version_info[0]
  18. except AttributeError:
  19.     VERSION = 1
  20.  
  21. callfunc_opcode_info = {
  22.     (0, 0): 'CALL_FUNCTION',
  23.     (1, 0): 'CALL_FUNCTION_VAR',
  24.     (0, 1): 'CALL_FUNCTION_KW',
  25.     (1, 1): 'CALL_FUNCTION_VAR_KW' }
  26. LOOP = 1
  27. EXCEPT = 2
  28. TRY_FINALLY = 3
  29. END_FINALLY = 4
  30.  
  31. def compileFile(filename, display = 0):
  32.     f = open(filename, 'U')
  33.     buf = f.read()
  34.     f.close()
  35.     mod = Module(buf, filename)
  36.     
  37.     try:
  38.         mod.compile(display)
  39.     except SyntaxError:
  40.         raise 
  41.  
  42.     f = open(filename + 'c', 'wb')
  43.     mod.dump(f)
  44.     f.close()
  45.  
  46.  
  47. def compile(source, filename, mode, flags = None, dont_inherit = None):
  48.     if flags is not None or dont_inherit is not None:
  49.         raise RuntimeError, 'not implemented yet'
  50.     
  51.     if mode == 'single':
  52.         gen = Interactive(source, filename)
  53.     elif mode == 'exec':
  54.         gen = Module(source, filename)
  55.     elif mode == 'eval':
  56.         gen = Expression(source, filename)
  57.     else:
  58.         raise ValueError("compile() 3rd arg must be 'exec' or 'eval' or 'single'")
  59.     gen.compile()
  60.     return gen.code
  61.  
  62.  
  63. class AbstractCompileMode:
  64.     mode = None
  65.     
  66.     def __init__(self, source, filename):
  67.         self.source = source
  68.         self.filename = filename
  69.         self.code = None
  70.  
  71.     
  72.     def _get_tree(self):
  73.         tree = parse(self.source, self.mode)
  74.         misc.set_filename(self.filename, tree)
  75.         syntax.check(tree)
  76.         return tree
  77.  
  78.     
  79.     def compile(self):
  80.         pass
  81.  
  82.     
  83.     def getCode(self):
  84.         return self.code
  85.  
  86.  
  87.  
  88. class Expression(AbstractCompileMode):
  89.     mode = 'eval'
  90.     
  91.     def compile(self):
  92.         tree = self._get_tree()
  93.         gen = ExpressionCodeGenerator(tree)
  94.         self.code = gen.getCode()
  95.  
  96.  
  97.  
  98. class Interactive(AbstractCompileMode):
  99.     mode = 'single'
  100.     
  101.     def compile(self):
  102.         tree = self._get_tree()
  103.         gen = InteractiveCodeGenerator(tree)
  104.         self.code = gen.getCode()
  105.  
  106.  
  107.  
  108. class Module(AbstractCompileMode):
  109.     mode = 'exec'
  110.     
  111.     def compile(self, display = 0):
  112.         tree = self._get_tree()
  113.         gen = ModuleCodeGenerator(tree)
  114.         if display:
  115.             import pprint as pprint
  116.             print pprint.pprint(tree)
  117.         
  118.         self.code = gen.getCode()
  119.  
  120.     
  121.     def dump(self, f):
  122.         f.write(self.getPycHeader())
  123.         marshal.dump(self.code, f)
  124.  
  125.     MAGIC = imp.get_magic()
  126.     
  127.     def getPycHeader(self):
  128.         mtime = os.path.getmtime(self.filename)
  129.         mtime = struct.pack('<i', mtime)
  130.         return self.MAGIC + mtime
  131.  
  132.  
  133.  
  134. class LocalNameFinder:
  135.     
  136.     def __init__(self, names = ()):
  137.         self.names = misc.Set()
  138.         self.globals = misc.Set()
  139.         for name in names:
  140.             self.names.add(name)
  141.         
  142.  
  143.     
  144.     def getLocals(self):
  145.         for elt in self.globals.elements():
  146.             if self.names.has_elt(elt):
  147.                 self.names.remove(elt)
  148.                 continue
  149.         
  150.         return self.names
  151.  
  152.     
  153.     def visitDict(self, node):
  154.         pass
  155.  
  156.     
  157.     def visitGlobal(self, node):
  158.         for name in node.names:
  159.             self.globals.add(name)
  160.         
  161.  
  162.     
  163.     def visitFunction(self, node):
  164.         self.names.add(node.name)
  165.  
  166.     
  167.     def visitLambda(self, node):
  168.         pass
  169.  
  170.     
  171.     def visitImport(self, node):
  172.         for name, alias in node.names:
  173.             if not alias:
  174.                 pass
  175.             self.names.add(name)
  176.         
  177.  
  178.     
  179.     def visitFrom(self, node):
  180.         for name, alias in node.names:
  181.             if not alias:
  182.                 pass
  183.             self.names.add(name)
  184.         
  185.  
  186.     
  187.     def visitClass(self, node):
  188.         self.names.add(node.name)
  189.  
  190.     
  191.     def visitAssName(self, node):
  192.         self.names.add(node.name)
  193.  
  194.  
  195.  
  196. def is_constant_false(node):
  197.     if isinstance(node, ast.Const):
  198.         if not node.value:
  199.             return 1
  200.         
  201.     
  202.     return 0
  203.  
  204.  
  205. class CodeGenerator:
  206.     optimized = 0
  207.     __initialized = None
  208.     class_name = None
  209.     
  210.     def __init__(self):
  211.         if self._CodeGenerator__initialized is None:
  212.             self.initClass()
  213.             self.__class__._CodeGenerator__initialized = 1
  214.         
  215.         self.checkClass()
  216.         self.locals = misc.Stack()
  217.         self.setups = misc.Stack()
  218.         self.last_lineno = None
  219.         self._setupGraphDelegation()
  220.         self._div_op = 'BINARY_DIVIDE'
  221.         futures = self.get_module().futures
  222.         for feature in futures:
  223.             if feature == 'division':
  224.                 self.graph.setFlag(CO_FUTURE_DIVISION)
  225.                 self._div_op = 'BINARY_TRUE_DIVIDE'
  226.                 continue
  227.             if feature == 'absolute_import':
  228.                 self.graph.setFlag(CO_FUTURE_ABSIMPORT)
  229.                 continue
  230.             if feature == 'with_statement':
  231.                 self.graph.setFlag(CO_FUTURE_WITH_STATEMENT)
  232.                 continue
  233.         
  234.  
  235.     
  236.     def initClass(self):
  237.         pass
  238.  
  239.     
  240.     def checkClass(self):
  241.         
  242.         try:
  243.             pass
  244.         except AssertionError:
  245.             msg = None
  246.             intro = 'Bad class construction for %s' % self.__class__.__name__
  247.             raise AssertionError, intro
  248.  
  249.  
  250.     
  251.     def _setupGraphDelegation(self):
  252.         self.emit = self.graph.emit
  253.         self.newBlock = self.graph.newBlock
  254.         self.startBlock = self.graph.startBlock
  255.         self.nextBlock = self.graph.nextBlock
  256.         self.setDocstring = self.graph.setDocstring
  257.  
  258.     
  259.     def getCode(self):
  260.         return self.graph.getCode()
  261.  
  262.     
  263.     def mangle(self, name):
  264.         if self.class_name is not None:
  265.             return misc.mangle(name, self.class_name)
  266.         else:
  267.             return name
  268.  
  269.     
  270.     def parseSymbols(self, tree):
  271.         s = symbols.SymbolVisitor()
  272.         walk(tree, s)
  273.         return s.scopes
  274.  
  275.     
  276.     def get_module(self):
  277.         raise RuntimeError, 'should be implemented by subclasses'
  278.  
  279.     
  280.     def isLocalName(self, name):
  281.         return self.locals.top().has_elt(name)
  282.  
  283.     
  284.     def storeName(self, name):
  285.         self._nameOp('STORE', name)
  286.  
  287.     
  288.     def loadName(self, name):
  289.         self._nameOp('LOAD', name)
  290.  
  291.     
  292.     def delName(self, name):
  293.         self._nameOp('DELETE', name)
  294.  
  295.     
  296.     def _nameOp(self, prefix, name):
  297.         name = self.mangle(name)
  298.         scope = self.scope.check_name(name)
  299.         if scope == SC_LOCAL:
  300.             if not self.optimized:
  301.                 self.emit(prefix + '_NAME', name)
  302.             else:
  303.                 self.emit(prefix + '_FAST', name)
  304.         elif scope == SC_GLOBAL:
  305.             if not self.optimized:
  306.                 self.emit(prefix + '_NAME', name)
  307.             else:
  308.                 self.emit(prefix + '_GLOBAL', name)
  309.         elif scope == SC_FREE or scope == SC_CELL:
  310.             self.emit(prefix + '_DEREF', name)
  311.         else:
  312.             raise RuntimeError, 'unsupported scope for var %s: %d' % (name, scope)
  313.  
  314.     
  315.     def _implicitNameOp(self, prefix, name):
  316.         if self.optimized:
  317.             self.emit(prefix + '_FAST', name)
  318.         else:
  319.             self.emit(prefix + '_NAME', name)
  320.  
  321.     
  322.     def set_lineno(self, node, force = False):
  323.         lineno = getattr(node, 'lineno', None)
  324.         if lineno is not None:
  325.             if lineno != self.last_lineno or force:
  326.                 self.emit('SET_LINENO', lineno)
  327.                 self.last_lineno = lineno
  328.                 return True
  329.             
  330.         return False
  331.  
  332.     NameFinder = LocalNameFinder
  333.     FunctionGen = None
  334.     ClassGen = None
  335.     
  336.     def visitModule(self, node):
  337.         self.scopes = self.parseSymbols(node)
  338.         self.scope = self.scopes[node]
  339.         self.emit('SET_LINENO', 0)
  340.         if node.doc:
  341.             self.emit('LOAD_CONST', node.doc)
  342.             self.storeName('__doc__')
  343.         
  344.         lnf = walk(node.node, self.NameFinder(), verbose = 0)
  345.         self.locals.push(lnf.getLocals())
  346.         self.visit(node.node)
  347.         self.emit('LOAD_CONST', None)
  348.         self.emit('RETURN_VALUE')
  349.  
  350.     
  351.     def visitExpression(self, node):
  352.         self.set_lineno(node)
  353.         self.scopes = self.parseSymbols(node)
  354.         self.scope = self.scopes[node]
  355.         self.visit(node.node)
  356.         self.emit('RETURN_VALUE')
  357.  
  358.     
  359.     def visitFunction(self, node):
  360.         self._visitFuncOrLambda(node, isLambda = 0)
  361.         if node.doc:
  362.             self.setDocstring(node.doc)
  363.         
  364.         self.storeName(node.name)
  365.  
  366.     
  367.     def visitLambda(self, node):
  368.         self._visitFuncOrLambda(node, isLambda = 1)
  369.  
  370.     
  371.     def _visitFuncOrLambda(self, node, isLambda = 0):
  372.         if not isLambda and node.decorators:
  373.             for decorator in node.decorators.nodes:
  374.                 self.visit(decorator)
  375.             
  376.             ndecorators = len(node.decorators.nodes)
  377.         else:
  378.             ndecorators = 0
  379.         gen = self.FunctionGen(node, self.scopes, isLambda, self.class_name, self.get_module())
  380.         walk(node.code, gen)
  381.         gen.finish()
  382.         self.set_lineno(node)
  383.         for default in node.defaults:
  384.             self.visit(default)
  385.         
  386.         self._makeClosure(gen, len(node.defaults))
  387.         for i in range(ndecorators):
  388.             self.emit('CALL_FUNCTION', 1)
  389.         
  390.  
  391.     
  392.     def visitClass(self, node):
  393.         gen = self.ClassGen(node, self.scopes, self.get_module())
  394.         walk(node.code, gen)
  395.         gen.finish()
  396.         self.set_lineno(node)
  397.         self.emit('LOAD_CONST', node.name)
  398.         for base in node.bases:
  399.             self.visit(base)
  400.         
  401.         self.emit('BUILD_TUPLE', len(node.bases))
  402.         self._makeClosure(gen, 0)
  403.         self.emit('CALL_FUNCTION', 0)
  404.         self.emit('BUILD_CLASS')
  405.         self.storeName(node.name)
  406.  
  407.     
  408.     def visitIf(self, node):
  409.         end = self.newBlock()
  410.         numtests = len(node.tests)
  411.         for i in range(numtests):
  412.             (test, suite) = node.tests[i]
  413.             if is_constant_false(test):
  414.                 continue
  415.             
  416.             self.set_lineno(test)
  417.             self.visit(test)
  418.             nextTest = self.newBlock()
  419.             self.emit('JUMP_IF_FALSE', nextTest)
  420.             self.nextBlock()
  421.             self.emit('POP_TOP')
  422.             self.visit(suite)
  423.             self.emit('JUMP_FORWARD', end)
  424.             self.startBlock(nextTest)
  425.             self.emit('POP_TOP')
  426.         
  427.         if node.else_:
  428.             self.visit(node.else_)
  429.         
  430.         self.nextBlock(end)
  431.  
  432.     
  433.     def visitWhile(self, node):
  434.         self.set_lineno(node)
  435.         loop = self.newBlock()
  436.         else_ = self.newBlock()
  437.         after = self.newBlock()
  438.         self.emit('SETUP_LOOP', after)
  439.         self.nextBlock(loop)
  440.         self.setups.push((LOOP, loop))
  441.         self.set_lineno(node, force = True)
  442.         self.visit(node.test)
  443.         if not else_:
  444.             pass
  445.         self.emit('JUMP_IF_FALSE', after)
  446.         self.nextBlock()
  447.         self.emit('POP_TOP')
  448.         self.visit(node.body)
  449.         self.emit('JUMP_ABSOLUTE', loop)
  450.         self.startBlock(else_)
  451.         self.emit('POP_TOP')
  452.         self.emit('POP_BLOCK')
  453.         self.setups.pop()
  454.         if node.else_:
  455.             self.visit(node.else_)
  456.         
  457.         self.nextBlock(after)
  458.  
  459.     
  460.     def visitFor(self, node):
  461.         start = self.newBlock()
  462.         anchor = self.newBlock()
  463.         after = self.newBlock()
  464.         self.setups.push((LOOP, start))
  465.         self.set_lineno(node)
  466.         self.emit('SETUP_LOOP', after)
  467.         self.visit(node.list)
  468.         self.emit('GET_ITER')
  469.         self.nextBlock(start)
  470.         self.set_lineno(node, force = 1)
  471.         self.emit('FOR_ITER', anchor)
  472.         self.visit(node.assign)
  473.         self.visit(node.body)
  474.         self.emit('JUMP_ABSOLUTE', start)
  475.         self.nextBlock(anchor)
  476.         self.emit('POP_BLOCK')
  477.         self.setups.pop()
  478.         if node.else_:
  479.             self.visit(node.else_)
  480.         
  481.         self.nextBlock(after)
  482.  
  483.     
  484.     def visitBreak(self, node):
  485.         if not self.setups:
  486.             raise SyntaxError, "'break' outside loop (%s, %d)" % (node.filename, node.lineno)
  487.         
  488.         self.set_lineno(node)
  489.         self.emit('BREAK_LOOP')
  490.  
  491.     
  492.     def visitContinue(self, node):
  493.         if not self.setups:
  494.             raise SyntaxError, "'continue' outside loop (%s, %d)" % (node.filename, node.lineno)
  495.         
  496.         (kind, block) = self.setups.top()
  497.         if kind == LOOP:
  498.             self.set_lineno(node)
  499.             self.emit('JUMP_ABSOLUTE', block)
  500.             self.nextBlock()
  501.         elif kind == EXCEPT or kind == TRY_FINALLY:
  502.             self.set_lineno(node)
  503.             top = len(self.setups)
  504.             while top > 0:
  505.                 top = top - 1
  506.                 (kind, loop_block) = self.setups[top]
  507.                 if kind == LOOP:
  508.                     break
  509.                     continue
  510.             if kind != LOOP:
  511.                 raise SyntaxError, "'continue' outside loop (%s, %d)" % (node.filename, node.lineno)
  512.             
  513.             self.emit('CONTINUE_LOOP', loop_block)
  514.             self.nextBlock()
  515.         elif kind == END_FINALLY:
  516.             msg = "'continue' not allowed inside 'finally' clause (%s, %d)"
  517.             raise SyntaxError, msg % (node.filename, node.lineno)
  518.         
  519.  
  520.     
  521.     def visitTest(self, node, jump):
  522.         end = self.newBlock()
  523.         for child in node.nodes[:-1]:
  524.             self.visit(child)
  525.             self.emit(jump, end)
  526.             self.nextBlock()
  527.             self.emit('POP_TOP')
  528.         
  529.         self.visit(node.nodes[-1])
  530.         self.nextBlock(end)
  531.  
  532.     
  533.     def visitAnd(self, node):
  534.         self.visitTest(node, 'JUMP_IF_FALSE')
  535.  
  536.     
  537.     def visitOr(self, node):
  538.         self.visitTest(node, 'JUMP_IF_TRUE')
  539.  
  540.     
  541.     def visitIfExp(self, node):
  542.         endblock = self.newBlock()
  543.         elseblock = self.newBlock()
  544.         self.visit(node.test)
  545.         self.emit('JUMP_IF_FALSE', elseblock)
  546.         self.emit('POP_TOP')
  547.         self.visit(node.then)
  548.         self.emit('JUMP_FORWARD', endblock)
  549.         self.nextBlock(elseblock)
  550.         self.emit('POP_TOP')
  551.         self.visit(node.else_)
  552.         self.nextBlock(endblock)
  553.  
  554.     
  555.     def visitCompare(self, node):
  556.         self.visit(node.expr)
  557.         cleanup = self.newBlock()
  558.         for op, code in node.ops[:-1]:
  559.             self.visit(code)
  560.             self.emit('DUP_TOP')
  561.             self.emit('ROT_THREE')
  562.             self.emit('COMPARE_OP', op)
  563.             self.emit('JUMP_IF_FALSE', cleanup)
  564.             self.nextBlock()
  565.             self.emit('POP_TOP')
  566.         
  567.         if node.ops:
  568.             (op, code) = node.ops[-1]
  569.             self.visit(code)
  570.             self.emit('COMPARE_OP', op)
  571.         
  572.         if len(node.ops) > 1:
  573.             end = self.newBlock()
  574.             self.emit('JUMP_FORWARD', end)
  575.             self.startBlock(cleanup)
  576.             self.emit('ROT_TWO')
  577.             self.emit('POP_TOP')
  578.             self.nextBlock(end)
  579.         
  580.  
  581.     __list_count = 0
  582.     
  583.     def visitListComp(self, node):
  584.         self.set_lineno(node)
  585.         append = '$append%d' % self._CodeGenerator__list_count
  586.         self._CodeGenerator__list_count = self._CodeGenerator__list_count + 1
  587.         self.emit('BUILD_LIST', 0)
  588.         self.emit('DUP_TOP')
  589.         self.emit('LOAD_ATTR', 'append')
  590.         self._implicitNameOp('STORE', append)
  591.         stack = []
  592.         for i, for_ in zip(range(len(node.quals)), node.quals):
  593.             (start, anchor) = self.visit(for_)
  594.             cont = None
  595.             for if_ in for_.ifs:
  596.                 if cont is None:
  597.                     cont = self.newBlock()
  598.                 
  599.                 self.visit(if_, cont)
  600.             
  601.             stack.insert(0, (start, cont, anchor))
  602.         
  603.         self._implicitNameOp('LOAD', append)
  604.         self.visit(node.expr)
  605.         self.emit('CALL_FUNCTION', 1)
  606.         self.emit('POP_TOP')
  607.         for start, cont, anchor in stack:
  608.             if cont:
  609.                 skip_one = self.newBlock()
  610.                 self.emit('JUMP_FORWARD', skip_one)
  611.                 self.startBlock(cont)
  612.                 self.emit('POP_TOP')
  613.                 self.nextBlock(skip_one)
  614.             
  615.             self.emit('JUMP_ABSOLUTE', start)
  616.             self.startBlock(anchor)
  617.         
  618.         self._implicitNameOp('DELETE', append)
  619.         self._CodeGenerator__list_count = self._CodeGenerator__list_count - 1
  620.  
  621.     
  622.     def visitListCompFor(self, node):
  623.         start = self.newBlock()
  624.         anchor = self.newBlock()
  625.         self.visit(node.list)
  626.         self.emit('GET_ITER')
  627.         self.nextBlock(start)
  628.         self.set_lineno(node, force = True)
  629.         self.emit('FOR_ITER', anchor)
  630.         self.nextBlock()
  631.         self.visit(node.assign)
  632.         return (start, anchor)
  633.  
  634.     
  635.     def visitListCompIf(self, node, branch):
  636.         self.set_lineno(node, force = True)
  637.         self.visit(node.test)
  638.         self.emit('JUMP_IF_FALSE', branch)
  639.         self.newBlock()
  640.         self.emit('POP_TOP')
  641.  
  642.     
  643.     def _makeClosure(self, gen, args):
  644.         frees = gen.scope.get_free_vars()
  645.         if frees:
  646.             for name in frees:
  647.                 self.emit('LOAD_CLOSURE', name)
  648.             
  649.             self.emit('BUILD_TUPLE', len(frees))
  650.             self.emit('LOAD_CONST', gen)
  651.             self.emit('MAKE_CLOSURE', args)
  652.         else:
  653.             self.emit('LOAD_CONST', gen)
  654.             self.emit('MAKE_FUNCTION', args)
  655.  
  656.     
  657.     def visitGenExpr(self, node):
  658.         gen = GenExprCodeGenerator(node, self.scopes, self.class_name, self.get_module())
  659.         walk(node.code, gen)
  660.         gen.finish()
  661.         self.set_lineno(node)
  662.         self._makeClosure(gen, 0)
  663.         self.visit(node.code.quals[0].iter)
  664.         self.emit('GET_ITER')
  665.         self.emit('CALL_FUNCTION', 1)
  666.  
  667.     
  668.     def visitGenExprInner(self, node):
  669.         self.set_lineno(node)
  670.         stack = []
  671.         for i, for_ in zip(range(len(node.quals)), node.quals):
  672.             (start, anchor, end) = self.visit(for_)
  673.             cont = None
  674.             for if_ in for_.ifs:
  675.                 if cont is None:
  676.                     cont = self.newBlock()
  677.                 
  678.                 self.visit(if_, cont)
  679.             
  680.             stack.insert(0, (start, cont, anchor, end))
  681.         
  682.         self.visit(node.expr)
  683.         self.emit('YIELD_VALUE')
  684.         self.emit('POP_TOP')
  685.         for start, cont, anchor, end in stack:
  686.             if cont:
  687.                 skip_one = self.newBlock()
  688.                 self.emit('JUMP_FORWARD', skip_one)
  689.                 self.startBlock(cont)
  690.                 self.emit('POP_TOP')
  691.                 self.nextBlock(skip_one)
  692.             
  693.             self.emit('JUMP_ABSOLUTE', start)
  694.             self.startBlock(anchor)
  695.             self.emit('POP_BLOCK')
  696.             self.setups.pop()
  697.             self.startBlock(end)
  698.         
  699.         self.emit('LOAD_CONST', None)
  700.  
  701.     
  702.     def visitGenExprFor(self, node):
  703.         start = self.newBlock()
  704.         anchor = self.newBlock()
  705.         end = self.newBlock()
  706.         self.setups.push((LOOP, start))
  707.         self.emit('SETUP_LOOP', end)
  708.         if node.is_outmost:
  709.             self.loadName('.0')
  710.         else:
  711.             self.visit(node.iter)
  712.             self.emit('GET_ITER')
  713.         self.nextBlock(start)
  714.         self.set_lineno(node, force = True)
  715.         self.emit('FOR_ITER', anchor)
  716.         self.nextBlock()
  717.         self.visit(node.assign)
  718.         return (start, anchor, end)
  719.  
  720.     
  721.     def visitGenExprIf(self, node, branch):
  722.         self.set_lineno(node, force = True)
  723.         self.visit(node.test)
  724.         self.emit('JUMP_IF_FALSE', branch)
  725.         self.newBlock()
  726.         self.emit('POP_TOP')
  727.  
  728.     
  729.     def visitAssert(self, node):
  730.         pass
  731.  
  732.     
  733.     def visitRaise(self, node):
  734.         self.set_lineno(node)
  735.         n = 0
  736.         if node.expr1:
  737.             self.visit(node.expr1)
  738.             n = n + 1
  739.         
  740.         if node.expr2:
  741.             self.visit(node.expr2)
  742.             n = n + 1
  743.         
  744.         if node.expr3:
  745.             self.visit(node.expr3)
  746.             n = n + 1
  747.         
  748.         self.emit('RAISE_VARARGS', n)
  749.  
  750.     
  751.     def visitTryExcept(self, node):
  752.         body = self.newBlock()
  753.         handlers = self.newBlock()
  754.         end = self.newBlock()
  755.         if node.else_:
  756.             lElse = self.newBlock()
  757.         else:
  758.             lElse = end
  759.         self.set_lineno(node)
  760.         self.emit('SETUP_EXCEPT', handlers)
  761.         self.nextBlock(body)
  762.         self.setups.push((EXCEPT, body))
  763.         self.visit(node.body)
  764.         self.emit('POP_BLOCK')
  765.         self.setups.pop()
  766.         self.emit('JUMP_FORWARD', lElse)
  767.         self.startBlock(handlers)
  768.         last = len(node.handlers) - 1
  769.         for i in range(len(node.handlers)):
  770.             (expr, target, body) = node.handlers[i]
  771.             self.set_lineno(expr)
  772.             if expr:
  773.                 self.emit('DUP_TOP')
  774.                 self.visit(expr)
  775.                 self.emit('COMPARE_OP', 'exception match')
  776.                 next = self.newBlock()
  777.                 self.emit('JUMP_IF_FALSE', next)
  778.                 self.nextBlock()
  779.                 self.emit('POP_TOP')
  780.             
  781.             self.emit('POP_TOP')
  782.             if target:
  783.                 self.visit(target)
  784.             else:
  785.                 self.emit('POP_TOP')
  786.             self.emit('POP_TOP')
  787.             self.visit(body)
  788.             self.emit('JUMP_FORWARD', end)
  789.             if expr:
  790.                 self.nextBlock(next)
  791.             else:
  792.                 self.nextBlock()
  793.             if expr:
  794.                 self.emit('POP_TOP')
  795.                 continue
  796.         
  797.         self.emit('END_FINALLY')
  798.         if node.else_:
  799.             self.nextBlock(lElse)
  800.             self.visit(node.else_)
  801.         
  802.         self.nextBlock(end)
  803.  
  804.     
  805.     def visitTryFinally(self, node):
  806.         body = self.newBlock()
  807.         final = self.newBlock()
  808.         self.set_lineno(node)
  809.         self.emit('SETUP_FINALLY', final)
  810.         self.nextBlock(body)
  811.         self.setups.push((TRY_FINALLY, body))
  812.         self.visit(node.body)
  813.         self.emit('POP_BLOCK')
  814.         self.setups.pop()
  815.         self.emit('LOAD_CONST', None)
  816.         self.nextBlock(final)
  817.         self.setups.push((END_FINALLY, final))
  818.         self.visit(node.final)
  819.         self.emit('END_FINALLY')
  820.         self.setups.pop()
  821.  
  822.     __with_count = 0
  823.     
  824.     def visitWith(self, node):
  825.         body = self.newBlock()
  826.         final = self.newBlock()
  827.         exitvar = '$exit%d' % self._CodeGenerator__with_count
  828.         valuevar = '$value%d' % self._CodeGenerator__with_count
  829.         self._CodeGenerator__with_count += 1
  830.         self.set_lineno(node)
  831.         self.visit(node.expr)
  832.         self.emit('DUP_TOP')
  833.         self.emit('LOAD_ATTR', '__exit__')
  834.         self._implicitNameOp('STORE', exitvar)
  835.         self.emit('LOAD_ATTR', '__enter__')
  836.         self.emit('CALL_FUNCTION', 0)
  837.         if node.vars is None:
  838.             self.emit('POP_TOP')
  839.         else:
  840.             self._implicitNameOp('STORE', valuevar)
  841.         self.emit('SETUP_FINALLY', final)
  842.         self.nextBlock(body)
  843.         self.setups.push((TRY_FINALLY, body))
  844.         if node.vars is not None:
  845.             self._implicitNameOp('LOAD', valuevar)
  846.             self._implicitNameOp('DELETE', valuevar)
  847.             self.visit(node.vars)
  848.         
  849.         self.visit(node.body)
  850.         self.emit('POP_BLOCK')
  851.         self.setups.pop()
  852.         self.emit('LOAD_CONST', None)
  853.         self.nextBlock(final)
  854.         self.setups.push((END_FINALLY, final))
  855.         self._implicitNameOp('LOAD', exitvar)
  856.         self._implicitNameOp('DELETE', exitvar)
  857.         self.emit('WITH_CLEANUP')
  858.         self.emit('END_FINALLY')
  859.         self.setups.pop()
  860.         self._CodeGenerator__with_count -= 1
  861.  
  862.     
  863.     def visitDiscard(self, node):
  864.         self.set_lineno(node)
  865.         self.visit(node.expr)
  866.         self.emit('POP_TOP')
  867.  
  868.     
  869.     def visitConst(self, node):
  870.         self.emit('LOAD_CONST', node.value)
  871.  
  872.     
  873.     def visitKeyword(self, node):
  874.         self.emit('LOAD_CONST', node.name)
  875.         self.visit(node.expr)
  876.  
  877.     
  878.     def visitGlobal(self, node):
  879.         pass
  880.  
  881.     
  882.     def visitName(self, node):
  883.         self.set_lineno(node)
  884.         self.loadName(node.name)
  885.  
  886.     
  887.     def visitPass(self, node):
  888.         self.set_lineno(node)
  889.  
  890.     
  891.     def visitImport(self, node):
  892.         self.set_lineno(node)
  893.         level = None if self.graph.checkFlag(CO_FUTURE_ABSIMPORT) else -1
  894.         for name, alias in node.names:
  895.             if VERSION > 1:
  896.                 self.emit('LOAD_CONST', level)
  897.                 self.emit('LOAD_CONST', None)
  898.             
  899.             self.emit('IMPORT_NAME', name)
  900.             mod = name.split('.')[0]
  901.             if alias:
  902.                 self._resolveDots(name)
  903.                 self.storeName(alias)
  904.                 continue
  905.             self.storeName(mod)
  906.         
  907.  
  908.     
  909.     def visitFrom(self, node):
  910.         self.set_lineno(node)
  911.         level = node.level
  912.         if level == 0 and not self.graph.checkFlag(CO_FUTURE_ABSIMPORT):
  913.             level = -1
  914.         
  915.         fromlist = map((lambda .0: (name, alias) = .0name), node.names)
  916.         if VERSION > 1:
  917.             self.emit('LOAD_CONST', level)
  918.             self.emit('LOAD_CONST', tuple(fromlist))
  919.         
  920.         self.emit('IMPORT_NAME', node.modname)
  921.         for name, alias in node.names:
  922.             if VERSION > 1:
  923.                 if name == '*':
  924.                     self.namespace = 0
  925.                     self.emit('IMPORT_STAR')
  926.                     return None
  927.                 else:
  928.                     self.emit('IMPORT_FROM', name)
  929.                     self._resolveDots(name)
  930.                     if not alias:
  931.                         pass
  932.                     self.storeName(name)
  933.             name == '*'
  934.             self.emit('IMPORT_FROM', name)
  935.         
  936.         self.emit('POP_TOP')
  937.  
  938.     
  939.     def _resolveDots(self, name):
  940.         elts = name.split('.')
  941.         if len(elts) == 1:
  942.             return None
  943.         
  944.         for elt in elts[1:]:
  945.             self.emit('LOAD_ATTR', elt)
  946.         
  947.  
  948.     
  949.     def visitGetattr(self, node):
  950.         self.visit(node.expr)
  951.         self.emit('LOAD_ATTR', self.mangle(node.attrname))
  952.  
  953.     
  954.     def visitAssign(self, node):
  955.         self.set_lineno(node)
  956.         self.visit(node.expr)
  957.         dups = len(node.nodes) - 1
  958.         for i in range(len(node.nodes)):
  959.             elt = node.nodes[i]
  960.             if i < dups:
  961.                 self.emit('DUP_TOP')
  962.             
  963.             if isinstance(elt, ast.Node):
  964.                 self.visit(elt)
  965.                 continue
  966.         
  967.  
  968.     
  969.     def visitAssName(self, node):
  970.         if node.flags == 'OP_ASSIGN':
  971.             self.storeName(node.name)
  972.         elif node.flags == 'OP_DELETE':
  973.             self.set_lineno(node)
  974.             self.delName(node.name)
  975.         else:
  976.             print 'oops', node.flags
  977.  
  978.     
  979.     def visitAssAttr(self, node):
  980.         self.visit(node.expr)
  981.         if node.flags == 'OP_ASSIGN':
  982.             self.emit('STORE_ATTR', self.mangle(node.attrname))
  983.         elif node.flags == 'OP_DELETE':
  984.             self.emit('DELETE_ATTR', self.mangle(node.attrname))
  985.         else:
  986.             print 'warning: unexpected flags:', node.flags
  987.             print node
  988.  
  989.     
  990.     def _visitAssSequence(self, node, op = 'UNPACK_SEQUENCE'):
  991.         if findOp(node) != 'OP_DELETE':
  992.             self.emit(op, len(node.nodes))
  993.         
  994.         for child in node.nodes:
  995.             self.visit(child)
  996.         
  997.  
  998.     if VERSION > 1:
  999.         visitAssTuple = _visitAssSequence
  1000.         visitAssList = _visitAssSequence
  1001.     else:
  1002.         
  1003.         def visitAssTuple(self, node):
  1004.             self._visitAssSequence(node, 'UNPACK_TUPLE')
  1005.  
  1006.         
  1007.         def visitAssList(self, node):
  1008.             self._visitAssSequence(node, 'UNPACK_LIST')
  1009.  
  1010.     
  1011.     def visitAugAssign(self, node):
  1012.         self.set_lineno(node)
  1013.         aug_node = wrap_aug(node.node)
  1014.         self.visit(aug_node, 'load')
  1015.         self.visit(node.expr)
  1016.         self.emit(self._augmented_opcode[node.op])
  1017.         self.visit(aug_node, 'store')
  1018.  
  1019.     _augmented_opcode = {
  1020.         '+=': 'INPLACE_ADD',
  1021.         '-=': 'INPLACE_SUBTRACT',
  1022.         '*=': 'INPLACE_MULTIPLY',
  1023.         '/=': 'INPLACE_DIVIDE',
  1024.         '//=': 'INPLACE_FLOOR_DIVIDE',
  1025.         '%=': 'INPLACE_MODULO',
  1026.         '**=': 'INPLACE_POWER',
  1027.         '>>=': 'INPLACE_RSHIFT',
  1028.         '<<=': 'INPLACE_LSHIFT',
  1029.         '&=': 'INPLACE_AND',
  1030.         '^=': 'INPLACE_XOR',
  1031.         '|=': 'INPLACE_OR' }
  1032.     
  1033.     def visitAugName(self, node, mode):
  1034.         if mode == 'load':
  1035.             self.loadName(node.name)
  1036.         elif mode == 'store':
  1037.             self.storeName(node.name)
  1038.         
  1039.  
  1040.     
  1041.     def visitAugGetattr(self, node, mode):
  1042.         if mode == 'load':
  1043.             self.visit(node.expr)
  1044.             self.emit('DUP_TOP')
  1045.             self.emit('LOAD_ATTR', self.mangle(node.attrname))
  1046.         elif mode == 'store':
  1047.             self.emit('ROT_TWO')
  1048.             self.emit('STORE_ATTR', self.mangle(node.attrname))
  1049.         
  1050.  
  1051.     
  1052.     def visitAugSlice(self, node, mode):
  1053.         if mode == 'load':
  1054.             self.visitSlice(node, 1)
  1055.         elif mode == 'store':
  1056.             slice = 0
  1057.             if node.lower:
  1058.                 slice = slice | 1
  1059.             
  1060.             if node.upper:
  1061.                 slice = slice | 2
  1062.             
  1063.             if slice == 0:
  1064.                 self.emit('ROT_TWO')
  1065.             elif slice == 3:
  1066.                 self.emit('ROT_FOUR')
  1067.             else:
  1068.                 self.emit('ROT_THREE')
  1069.             self.emit('STORE_SLICE+%d' % slice)
  1070.         
  1071.  
  1072.     
  1073.     def visitAugSubscript(self, node, mode):
  1074.         if mode == 'load':
  1075.             self.visitSubscript(node, 1)
  1076.         elif mode == 'store':
  1077.             self.emit('ROT_THREE')
  1078.             self.emit('STORE_SUBSCR')
  1079.         
  1080.  
  1081.     
  1082.     def visitExec(self, node):
  1083.         self.visit(node.expr)
  1084.         if node.locals is None:
  1085.             self.emit('LOAD_CONST', None)
  1086.         else:
  1087.             self.visit(node.locals)
  1088.         if node.globals is None:
  1089.             self.emit('DUP_TOP')
  1090.         else:
  1091.             self.visit(node.globals)
  1092.         self.emit('EXEC_STMT')
  1093.  
  1094.     
  1095.     def visitCallFunc(self, node):
  1096.         pos = 0
  1097.         kw = 0
  1098.         self.set_lineno(node)
  1099.         self.visit(node.node)
  1100.         for arg in node.args:
  1101.             self.visit(arg)
  1102.             if isinstance(arg, ast.Keyword):
  1103.                 kw = kw + 1
  1104.                 continue
  1105.             pos = pos + 1
  1106.         
  1107.         if node.star_args is not None:
  1108.             self.visit(node.star_args)
  1109.         
  1110.         if node.dstar_args is not None:
  1111.             self.visit(node.dstar_args)
  1112.         
  1113.         have_star = node.star_args is not None
  1114.         have_dstar = node.dstar_args is not None
  1115.         opcode = callfunc_opcode_info[(have_star, have_dstar)]
  1116.         self.emit(opcode, kw << 8 | pos)
  1117.  
  1118.     
  1119.     def visitPrint(self, node, newline = 0):
  1120.         self.set_lineno(node)
  1121.         if node.dest:
  1122.             self.visit(node.dest)
  1123.         
  1124.         for child in node.nodes:
  1125.             if node.dest:
  1126.                 self.emit('DUP_TOP')
  1127.             
  1128.             self.visit(child)
  1129.             if node.dest:
  1130.                 self.emit('ROT_TWO')
  1131.                 self.emit('PRINT_ITEM_TO')
  1132.                 continue
  1133.             self.emit('PRINT_ITEM')
  1134.         
  1135.         if node.dest and not newline:
  1136.             self.emit('POP_TOP')
  1137.         
  1138.  
  1139.     
  1140.     def visitPrintnl(self, node):
  1141.         self.visitPrint(node, newline = 1)
  1142.         if node.dest:
  1143.             self.emit('PRINT_NEWLINE_TO')
  1144.         else:
  1145.             self.emit('PRINT_NEWLINE')
  1146.  
  1147.     
  1148.     def visitReturn(self, node):
  1149.         self.set_lineno(node)
  1150.         self.visit(node.value)
  1151.         self.emit('RETURN_VALUE')
  1152.  
  1153.     
  1154.     def visitYield(self, node):
  1155.         self.set_lineno(node)
  1156.         self.visit(node.value)
  1157.         self.emit('YIELD_VALUE')
  1158.  
  1159.     
  1160.     def visitSlice(self, node, aug_flag = None):
  1161.         self.visit(node.expr)
  1162.         slice = 0
  1163.         if node.lower:
  1164.             self.visit(node.lower)
  1165.             slice = slice | 1
  1166.         
  1167.         if node.upper:
  1168.             self.visit(node.upper)
  1169.             slice = slice | 2
  1170.         
  1171.         if aug_flag:
  1172.             if slice == 0:
  1173.                 self.emit('DUP_TOP')
  1174.             elif slice == 3:
  1175.                 self.emit('DUP_TOPX', 3)
  1176.             else:
  1177.                 self.emit('DUP_TOPX', 2)
  1178.         
  1179.         if node.flags == 'OP_APPLY':
  1180.             self.emit('SLICE+%d' % slice)
  1181.         elif node.flags == 'OP_ASSIGN':
  1182.             self.emit('STORE_SLICE+%d' % slice)
  1183.         elif node.flags == 'OP_DELETE':
  1184.             self.emit('DELETE_SLICE+%d' % slice)
  1185.         else:
  1186.             print 'weird slice', node.flags
  1187.             raise 
  1188.  
  1189.     
  1190.     def visitSubscript(self, node, aug_flag = None):
  1191.         self.visit(node.expr)
  1192.         for sub in node.subs:
  1193.             self.visit(sub)
  1194.         
  1195.         if len(node.subs) > 1:
  1196.             self.emit('BUILD_TUPLE', len(node.subs))
  1197.         
  1198.         if aug_flag:
  1199.             self.emit('DUP_TOPX', 2)
  1200.         
  1201.         if node.flags == 'OP_APPLY':
  1202.             self.emit('BINARY_SUBSCR')
  1203.         elif node.flags == 'OP_ASSIGN':
  1204.             self.emit('STORE_SUBSCR')
  1205.         elif node.flags == 'OP_DELETE':
  1206.             self.emit('DELETE_SUBSCR')
  1207.         
  1208.  
  1209.     
  1210.     def binaryOp(self, node, op):
  1211.         self.visit(node.left)
  1212.         self.visit(node.right)
  1213.         self.emit(op)
  1214.  
  1215.     
  1216.     def visitAdd(self, node):
  1217.         return self.binaryOp(node, 'BINARY_ADD')
  1218.  
  1219.     
  1220.     def visitSub(self, node):
  1221.         return self.binaryOp(node, 'BINARY_SUBTRACT')
  1222.  
  1223.     
  1224.     def visitMul(self, node):
  1225.         return self.binaryOp(node, 'BINARY_MULTIPLY')
  1226.  
  1227.     
  1228.     def visitDiv(self, node):
  1229.         return self.binaryOp(node, self._div_op)
  1230.  
  1231.     
  1232.     def visitFloorDiv(self, node):
  1233.         return self.binaryOp(node, 'BINARY_FLOOR_DIVIDE')
  1234.  
  1235.     
  1236.     def visitMod(self, node):
  1237.         return self.binaryOp(node, 'BINARY_MODULO')
  1238.  
  1239.     
  1240.     def visitPower(self, node):
  1241.         return self.binaryOp(node, 'BINARY_POWER')
  1242.  
  1243.     
  1244.     def visitLeftShift(self, node):
  1245.         return self.binaryOp(node, 'BINARY_LSHIFT')
  1246.  
  1247.     
  1248.     def visitRightShift(self, node):
  1249.         return self.binaryOp(node, 'BINARY_RSHIFT')
  1250.  
  1251.     
  1252.     def unaryOp(self, node, op):
  1253.         self.visit(node.expr)
  1254.         self.emit(op)
  1255.  
  1256.     
  1257.     def visitInvert(self, node):
  1258.         return self.unaryOp(node, 'UNARY_INVERT')
  1259.  
  1260.     
  1261.     def visitUnarySub(self, node):
  1262.         return self.unaryOp(node, 'UNARY_NEGATIVE')
  1263.  
  1264.     
  1265.     def visitUnaryAdd(self, node):
  1266.         return self.unaryOp(node, 'UNARY_POSITIVE')
  1267.  
  1268.     
  1269.     def visitUnaryInvert(self, node):
  1270.         return self.unaryOp(node, 'UNARY_INVERT')
  1271.  
  1272.     
  1273.     def visitNot(self, node):
  1274.         return self.unaryOp(node, 'UNARY_NOT')
  1275.  
  1276.     
  1277.     def visitBackquote(self, node):
  1278.         return self.unaryOp(node, 'UNARY_CONVERT')
  1279.  
  1280.     
  1281.     def bitOp(self, nodes, op):
  1282.         self.visit(nodes[0])
  1283.         for node in nodes[1:]:
  1284.             self.visit(node)
  1285.             self.emit(op)
  1286.         
  1287.  
  1288.     
  1289.     def visitBitand(self, node):
  1290.         return self.bitOp(node.nodes, 'BINARY_AND')
  1291.  
  1292.     
  1293.     def visitBitor(self, node):
  1294.         return self.bitOp(node.nodes, 'BINARY_OR')
  1295.  
  1296.     
  1297.     def visitBitxor(self, node):
  1298.         return self.bitOp(node.nodes, 'BINARY_XOR')
  1299.  
  1300.     
  1301.     def visitEllipsis(self, node):
  1302.         self.emit('LOAD_CONST', Ellipsis)
  1303.  
  1304.     
  1305.     def visitTuple(self, node):
  1306.         self.set_lineno(node)
  1307.         for elt in node.nodes:
  1308.             self.visit(elt)
  1309.         
  1310.         self.emit('BUILD_TUPLE', len(node.nodes))
  1311.  
  1312.     
  1313.     def visitList(self, node):
  1314.         self.set_lineno(node)
  1315.         for elt in node.nodes:
  1316.             self.visit(elt)
  1317.         
  1318.         self.emit('BUILD_LIST', len(node.nodes))
  1319.  
  1320.     
  1321.     def visitSliceobj(self, node):
  1322.         for child in node.nodes:
  1323.             self.visit(child)
  1324.         
  1325.         self.emit('BUILD_SLICE', len(node.nodes))
  1326.  
  1327.     
  1328.     def visitDict(self, node):
  1329.         self.set_lineno(node)
  1330.         self.emit('BUILD_MAP', 0)
  1331.         for k, v in node.items:
  1332.             self.emit('DUP_TOP')
  1333.             self.visit(k)
  1334.             self.visit(v)
  1335.             self.emit('ROT_THREE')
  1336.             self.emit('STORE_SUBSCR')
  1337.         
  1338.  
  1339.  
  1340.  
  1341. class NestedScopeMixin:
  1342.     
  1343.     def initClass(self):
  1344.         self.__class__.NameFinder = LocalNameFinder
  1345.         self.__class__.FunctionGen = FunctionCodeGenerator
  1346.         self.__class__.ClassGen = ClassCodeGenerator
  1347.  
  1348.  
  1349.  
  1350. class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
  1351.     __super_init = CodeGenerator.__init__
  1352.     scopes = None
  1353.     
  1354.     def __init__(self, tree):
  1355.         self.graph = pyassem.PyFlowGraph('<module>', tree.filename)
  1356.         self.futures = future.find_futures(tree)
  1357.         self._ModuleCodeGenerator__super_init()
  1358.         walk(tree, self)
  1359.  
  1360.     
  1361.     def get_module(self):
  1362.         return self
  1363.  
  1364.  
  1365.  
  1366. class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):
  1367.     __super_init = CodeGenerator.__init__
  1368.     scopes = None
  1369.     futures = ()
  1370.     
  1371.     def __init__(self, tree):
  1372.         self.graph = pyassem.PyFlowGraph('<expression>', tree.filename)
  1373.         self._ExpressionCodeGenerator__super_init()
  1374.         walk(tree, self)
  1375.  
  1376.     
  1377.     def get_module(self):
  1378.         return self
  1379.  
  1380.  
  1381.  
  1382. class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):
  1383.     __super_init = CodeGenerator.__init__
  1384.     scopes = None
  1385.     futures = ()
  1386.     
  1387.     def __init__(self, tree):
  1388.         self.graph = pyassem.PyFlowGraph('<interactive>', tree.filename)
  1389.         self._InteractiveCodeGenerator__super_init()
  1390.         self.set_lineno(tree)
  1391.         walk(tree, self)
  1392.         self.emit('RETURN_VALUE')
  1393.  
  1394.     
  1395.     def get_module(self):
  1396.         return self
  1397.  
  1398.     
  1399.     def visitDiscard(self, node):
  1400.         self.visit(node.expr)
  1401.         self.emit('PRINT_EXPR')
  1402.  
  1403.  
  1404.  
  1405. class AbstractFunctionCode:
  1406.     optimized = 1
  1407.     lambdaCount = 0
  1408.     
  1409.     def __init__(self, func, scopes, isLambda, class_name, mod):
  1410.         self.class_name = class_name
  1411.         self.module = mod
  1412.         if isLambda:
  1413.             klass = FunctionCodeGenerator
  1414.             name = '<lambda.%d>' % klass.lambdaCount
  1415.             klass.lambdaCount = klass.lambdaCount + 1
  1416.         else:
  1417.             name = func.name
  1418.         (args, hasTupleArg) = generateArgList(func.argnames)
  1419.         self.graph = pyassem.PyFlowGraph(name, func.filename, args, optimized = 1)
  1420.         self.isLambda = isLambda
  1421.         self.super_init()
  1422.         if not isLambda and func.doc:
  1423.             self.setDocstring(func.doc)
  1424.         
  1425.         lnf = walk(func.code, self.NameFinder(args), verbose = 0)
  1426.         self.locals.push(lnf.getLocals())
  1427.         if func.varargs:
  1428.             self.graph.setFlag(CO_VARARGS)
  1429.         
  1430.         if func.kwargs:
  1431.             self.graph.setFlag(CO_VARKEYWORDS)
  1432.         
  1433.         self.set_lineno(func)
  1434.         if hasTupleArg:
  1435.             self.generateArgUnpack(func.argnames)
  1436.         
  1437.  
  1438.     
  1439.     def get_module(self):
  1440.         return self.module
  1441.  
  1442.     
  1443.     def finish(self):
  1444.         self.graph.startExitBlock()
  1445.         if not self.isLambda:
  1446.             self.emit('LOAD_CONST', None)
  1447.         
  1448.         self.emit('RETURN_VALUE')
  1449.  
  1450.     
  1451.     def generateArgUnpack(self, args):
  1452.         for i in range(len(args)):
  1453.             arg = args[i]
  1454.             if isinstance(arg, tuple):
  1455.                 self.emit('LOAD_FAST', '.%d' % i * 2)
  1456.                 self.unpackSequence(arg)
  1457.                 continue
  1458.         
  1459.  
  1460.     
  1461.     def unpackSequence(self, tup):
  1462.         if VERSION > 1:
  1463.             self.emit('UNPACK_SEQUENCE', len(tup))
  1464.         else:
  1465.             self.emit('UNPACK_TUPLE', len(tup))
  1466.         for elt in tup:
  1467.             if isinstance(elt, tuple):
  1468.                 self.unpackSequence(elt)
  1469.                 continue
  1470.             self._nameOp('STORE', elt)
  1471.         
  1472.  
  1473.     unpackTuple = unpackSequence
  1474.  
  1475.  
  1476. class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode, CodeGenerator):
  1477.     super_init = CodeGenerator.__init__
  1478.     scopes = None
  1479.     __super_init = AbstractFunctionCode.__init__
  1480.     
  1481.     def __init__(self, func, scopes, isLambda, class_name, mod):
  1482.         self.scopes = scopes
  1483.         self.scope = scopes[func]
  1484.         self._FunctionCodeGenerator__super_init(func, scopes, isLambda, class_name, mod)
  1485.         self.graph.setFreeVars(self.scope.get_free_vars())
  1486.         self.graph.setCellVars(self.scope.get_cell_vars())
  1487.         if self.scope.generator is not None:
  1488.             self.graph.setFlag(CO_GENERATOR)
  1489.         
  1490.  
  1491.  
  1492.  
  1493. class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode, CodeGenerator):
  1494.     super_init = CodeGenerator.__init__
  1495.     scopes = None
  1496.     __super_init = AbstractFunctionCode.__init__
  1497.     
  1498.     def __init__(self, gexp, scopes, class_name, mod):
  1499.         self.scopes = scopes
  1500.         self.scope = scopes[gexp]
  1501.         self._GenExprCodeGenerator__super_init(gexp, scopes, 1, class_name, mod)
  1502.         self.graph.setFreeVars(self.scope.get_free_vars())
  1503.         self.graph.setCellVars(self.scope.get_cell_vars())
  1504.         self.graph.setFlag(CO_GENERATOR)
  1505.  
  1506.  
  1507.  
  1508. class AbstractClassCode:
  1509.     
  1510.     def __init__(self, klass, scopes, module):
  1511.         self.class_name = klass.name
  1512.         self.module = module
  1513.         self.graph = pyassem.PyFlowGraph(klass.name, klass.filename, optimized = 0, klass = 1)
  1514.         self.super_init()
  1515.         lnf = walk(klass.code, self.NameFinder(), verbose = 0)
  1516.         self.locals.push(lnf.getLocals())
  1517.         self.graph.setFlag(CO_NEWLOCALS)
  1518.         if klass.doc:
  1519.             self.setDocstring(klass.doc)
  1520.         
  1521.  
  1522.     
  1523.     def get_module(self):
  1524.         return self.module
  1525.  
  1526.     
  1527.     def finish(self):
  1528.         self.graph.startExitBlock()
  1529.         self.emit('LOAD_LOCALS')
  1530.         self.emit('RETURN_VALUE')
  1531.  
  1532.  
  1533.  
  1534. class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):
  1535.     super_init = CodeGenerator.__init__
  1536.     scopes = None
  1537.     __super_init = AbstractClassCode.__init__
  1538.     
  1539.     def __init__(self, klass, scopes, module):
  1540.         self.scopes = scopes
  1541.         self.scope = scopes[klass]
  1542.         self._ClassCodeGenerator__super_init(klass, scopes, module)
  1543.         self.graph.setFreeVars(self.scope.get_free_vars())
  1544.         self.graph.setCellVars(self.scope.get_cell_vars())
  1545.         self.set_lineno(klass)
  1546.         self.emit('LOAD_GLOBAL', '__name__')
  1547.         self.storeName('__module__')
  1548.         if klass.doc:
  1549.             self.emit('LOAD_CONST', klass.doc)
  1550.             self.storeName('__doc__')
  1551.         
  1552.  
  1553.  
  1554.  
  1555. def generateArgList(arglist):
  1556.     args = []
  1557.     extra = []
  1558.     count = 0
  1559.     for i in range(len(arglist)):
  1560.         elt = arglist[i]
  1561.         if isinstance(elt, str):
  1562.             args.append(elt)
  1563.             continue
  1564.         if isinstance(elt, tuple):
  1565.             args.append(TupleArg(i * 2, elt))
  1566.             extra.extend(misc.flatten(elt))
  1567.             count = count + 1
  1568.             continue
  1569.         raise ValueError, 'unexpect argument type:', elt
  1570.     
  1571.     return (args + extra, count)
  1572.  
  1573.  
  1574. def findOp(node):
  1575.     v = OpFinder()
  1576.     walk(node, v, verbose = 0)
  1577.     return v.op
  1578.  
  1579.  
  1580. class OpFinder:
  1581.     
  1582.     def __init__(self):
  1583.         self.op = None
  1584.  
  1585.     
  1586.     def visitAssName(self, node):
  1587.         if self.op is None:
  1588.             self.op = node.flags
  1589.         elif self.op != node.flags:
  1590.             raise ValueError, 'mixed ops in stmt'
  1591.         
  1592.  
  1593.     visitAssAttr = visitAssName
  1594.     visitSubscript = visitAssName
  1595.  
  1596.  
  1597. class Delegator:
  1598.     
  1599.     def __init__(self, obj):
  1600.         self.obj = obj
  1601.  
  1602.     
  1603.     def __getattr__(self, attr):
  1604.         return getattr(self.obj, attr)
  1605.  
  1606.  
  1607.  
  1608. class AugGetattr(Delegator):
  1609.     pass
  1610.  
  1611.  
  1612. class AugName(Delegator):
  1613.     pass
  1614.  
  1615.  
  1616. class AugSlice(Delegator):
  1617.     pass
  1618.  
  1619.  
  1620. class AugSubscript(Delegator):
  1621.     pass
  1622.  
  1623. wrapper = {
  1624.     ast.Getattr: AugGetattr,
  1625.     ast.Name: AugName,
  1626.     ast.Slice: AugSlice,
  1627.     ast.Subscript: AugSubscript }
  1628.  
  1629. def wrap_aug(node):
  1630.     return wrapper[node.__class__](node)
  1631.  
  1632. if __name__ == '__main__':
  1633.     for file in sys.argv[1:]:
  1634.         compileFile(file)
  1635.     
  1636.  
  1637.